package com.wxapp.sale.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.core.filter.except.ThrowMyException;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.sale.api.enums.goods.GoodsPictureTypeEnum;
import com.wxapp.sale.api.pojo.entity.GoodsDO;
import com.wxapp.sale.api.pojo.entity.GoodsDetailDO;
import com.wxapp.sale.api.pojo.entity.GoodsFileDO;
import com.wxapp.sale.api.pojo.entity.GoodsTypeDO;
import com.wxapp.sale.api.pojo.vm.goods.PGoodsAddFileVm;
import com.wxapp.sale.api.pojo.vm.goods.PGoodsAllFileDetailVm;
import com.wxapp.sale.api.pojo.vm.goods.PGoodsDetailVm;
import com.wxapp.sale.api.pojo.vm.goods.PGoodsPageVm;
import com.wxapp.sale.api.pojo.vo.goods.QGoodsAddFileVo;
import com.wxapp.sale.api.pojo.vo.goods.QGoodsAddVo;
import com.wxapp.sale.api.pojo.vo.goods.QGoodsPageVo;
import com.wxapp.sale.api.pojo.vo.goods.QGoodsUpdateVo;
import com.wxapp.sale.service.mapper.GoodsDetailMapper;
import com.wxapp.sale.service.mapper.GoodsFileMapper;
import com.wxapp.sale.service.mapper.GoodsMapper;
import com.wxapp.sale.service.mapper.GoodsTypeMapper;
import com.wxapp.sale.service.service.GoodsService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

/**
 * @author lgl
 */
@Service
@RequiredArgsConstructor
public class GoodsServiceImpl extends IBaseService implements GoodsService {
    private final GoodsMapper goodsMapper;
    private final GoodsDetailMapper goodsDetailMapper;
    private final GoodsFileMapper goodsFileMapper;
    private final GoodsTypeMapper goodsTypeMapper;


    @Override
    public ResultVm<Page<PGoodsPageVm>> page(QGoodsPageVo qPageVo, UserVo userVo) {
        List<String> goodsTypeIds=new ArrayList<>();
        if (CheckUtil.isNotNullString(qPageVo.getTypePid())) {
            LambdaQueryWrapper<GoodsTypeDO> query = new LambdaQueryWrapper<>();
            query.select(GoodsTypeDO::getId, GoodsTypeDO::getName)
                    .eq(GoodsTypeDO::getPid, qPageVo.getTypePid())
                    .eq(GoodsTypeDO::getStatus, true);
            var goodTypes = goodsTypeMapper.selectList(query);
            if (CheckUtil.isNotNullList(goodTypes)) {
                goodsTypeIds = goodTypes.stream().map(GoodsTypeDO::getId).toList();
            }
        }
        var page = ConditionUtil.getPage(qPageVo, PGoodsPageVm.class);
        return success(goodsMapper.selectPageList(page, qPageVo,userVo==null?null:userVo.getId(),goodsTypeIds));
    }

    @Override
    public ResultVm<String> add(QGoodsAddVo qGoodsAddVo, UserVo userVo) {
        var userVoId = userVo.getId();
        var webappGoods = CopyUtil.copyObjectNew(qGoodsAddVo, GoodsDO::new, (s, r) -> {
            r.setOnSale(true);
            r.setCreateBy(userVoId);
            return null;
        });
        goodsMapper.insert(webappGoods);
        GoodsDetailDO goodsDetailDO = new GoodsDetailDO();
        goodsDetailDO.setGoodsId(webappGoods.getId());
        goodsDetailDO.setIntroduce(qGoodsAddVo.getIntroduce());
        goodsDetailDO.setSaleNum(0);
        goodsDetailDO.setCreateBy(userVoId);
        goodsDetailMapper.insert(goodsDetailDO);
        return success("添加成功");
    }

    @Override
    public ResultVm<String> update(QGoodsUpdateVo qGoodsUpdateVo, UserVo userVo) {
        var wxappGoodsDO = goodsMapper.selectById(qGoodsUpdateVo.getId());
        if (CheckUtil.isNullObject(wxappGoodsDO)) {
            return error("没有找到商品信息");
        }
        if (qGoodsUpdateVo.getOnSale() == null && Boolean.TRUE.equals(wxappGoodsDO.getOnSale())) {
            return error("请先下架商品在更新");
        }
        CopyUtil.copyObject(qGoodsUpdateVo, wxappGoodsDO, (s, r) -> {
            r.setCreateBy(userVo.getId());
            return null;
        });
        goodsMapper.updateById(wxappGoodsDO);
        if (CheckUtil.isNotNullObject(qGoodsUpdateVo.getIntroduce())) {
            var query = new LambdaUpdateWrapper<GoodsDetailDO>();
            query.eq(GoodsDetailDO::getGoodsId, qGoodsUpdateVo.getId()).eq(GoodsDetailDO::getStatus, true)
                    .set(GoodsDetailDO::getIntroduce, qGoodsUpdateVo.getIntroduce());
            goodsDetailMapper.update(null, query);
        }
        return success("更新成功");
    }

    @Override
    public ResultVm<String> delGoods(String id) {
        LambdaQueryWrapper<GoodsDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GoodsDO::getId, id).eq(GoodsDO::getStatus, true);
        var goodsDO = goodsMapper.selectFirst(wrapper);
        if (CheckUtil.isNullObject(goodsDO)) {
            return error("没有找到商品信息");
        }
        if (Boolean.TRUE.equals(goodsDO.getOnSale())) {
            return error("商品正在销售请下架后删除");
        }
        goodsDO.setStatus(false);
        goodsMapper.updateById(goodsDO);
        var query = new LambdaUpdateWrapper<GoodsDetailDO>();
        query.eq(GoodsDetailDO::getGoodsId, id).eq(GoodsDetailDO::getStatus, true)
                .set(GoodsDetailDO::getStatus, false);
        goodsDetailMapper.update(null, query);
        return success("删除商品成功");
    }

    @Override
    public ResultVm<PGoodsDetailVm> detail(String id) throws ThrowMyException {
        return success(getDetail(id, PGoodsDetailVm::new));
    }

    @Override
    public ResultVm<String> addFile(String id, QGoodsAddFileVo qAddVo, UserVo userVo) {
        var update = new LambdaUpdateWrapper<GoodsFileDO>();
        update.eq(GoodsFileDO::getStatus, true)
                .eq(GoodsFileDO::getGoodsId, id)
                .set(GoodsFileDO::getStatus, false);
        goodsFileMapper.update(null, update);
        List<GoodsFileDO> list = new ArrayList<>();
        if (CheckUtil.isNotNullList(qAddVo.getFileUrls())) {
            qAddVo.getFileUrls().forEach(s -> list.add(new GoodsFileDO(id, GoodsPictureTypeEnum.OTHER, s, false)));
        }
        if (CheckUtil.isNotNullList(qAddVo.getImageUrls())) {
            qAddVo.getImageUrls().forEach(s -> list.add(new GoodsFileDO(id, GoodsPictureTypeEnum.IMAGE, s, false)));
        }
        if (CheckUtil.isNotNullList(list)) {
            goodsFileMapper.insertBatch(list);
        }
        return success("添加成功");
    }

    @Override
    public ResultVm<PGoodsAddFileVm> getFiles(String id) {
        var query = new LambdaQueryWrapper<GoodsFileDO>();
        query.eq(GoodsFileDO::getStatus, true)
                .eq(GoodsFileDO::getGoodsId, id);
        var goodsFiles = goodsFileMapper.selectList(query);
        PGoodsAddFileVm pGoodsAddFileVm = new PGoodsAddFileVm();
        List<String> imageUrls = new ArrayList<>();
        List<String> fileUrls = new ArrayList<>();
        goodsFiles.forEach(s -> {
            switch (s.getType()) {
                case IMAGE:
                    imageUrls.add(s.getUrl());
                    break;
                case OTHER:
                    fileUrls.add(s.getUrl());
                    break;
                default:
                    break;
            }
        });
        pGoodsAddFileVm.setFileUrls(fileUrls);
        pGoodsAddFileVm.setImageUrls(imageUrls);
        return success(pGoodsAddFileVm);
    }
    @Override
    public  ResultVm<List<PGoodsAllFileDetailVm>> getFilesDetail(String id){
        var query = new LambdaQueryWrapper<GoodsFileDO>();
        query.eq(GoodsFileDO::getStatus, true)
                .eq(GoodsFileDO::getGoodsId, id);
        var goodsFiles = goodsFileMapper.selectList(query);
        return success(CopyUtil.copyListNew(goodsFiles, PGoodsAllFileDetailVm::new,null));
    }
    @Override
    public ResultVm<List<PGoodsPageVm>> list(List<String> ids, UserVo userVo) {
        LambdaQueryWrapper<GoodsDO> query = new LambdaQueryWrapper<>();
        query.eq(GoodsDO::getStatus, true)
                .in(GoodsDO::getId, ids)
                .eq(GoodsDO::getCreateBy,userVo.getId());
        List<GoodsDO> data = goodsMapper.selectList(query);
        return success( CopyUtil.copyListNew(data, PGoodsPageVm::new, null));
    }

    private <T extends PGoodsDetailVm> T getDetail(String id, Supplier<T> source) throws ThrowMyException {
        var wrapper = new LambdaQueryWrapper<GoodsDO>();
        wrapper.eq(GoodsDO::getId, id).eq(GoodsDO::getStatus, true);
        var goodsDO = goodsMapper.selectFirst(wrapper);
        if (CheckUtil.isNullObject(goodsDO)) {
            throw new ThrowMyException("没有找到商品信息");
        }
        var vm = CopyUtil.copyObjectNew(goodsDO, source, null);
        var query = new LambdaQueryWrapper<GoodsDetailDO>();
        query.eq(GoodsDetailDO::getGoodsId, id).eq(GoodsDetailDO::getStatus, true);
        var goodsDetail = goodsDetailMapper.selectFirst(query);
        if (CheckUtil.isNotNullObject(goodsDetail)) {
            vm.setIntroduce(goodsDetail.getIntroduce());
        }
        return vm;
    }
}
